function dbc2xml(dbc)

%DBC2XML - generate xml file from a Vector DBC file for TargetLink DDManager to import
%
%   Syntax:  dbc2xml(dbc)
%
%   Inputs:
%     dbc - the dbc file name
%
%   Outputs:
%     CAN_IO_ddImport.xml
%
%   Example: 
%     dbc2xml('demo.dbc')
%
%
%
%   See also: 

%   Author(s): Xiaobiao Huang
%   Copyright 2013-2020 The Xiaobiao Studio.
%   $Revision: 1.0.0.0 $  $Date: 2023/06/21 19:55:54 $

candb = canDatabase(dbc);

docNode = com.mathworks.xml.XMLUtils.createDocument... 
    ('ddObj');
docRootNode = docNode.getDocumentElement;

docRootNode.setAttribute('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance');
docRootNode.setAttribute('xmlns','http://www.dspace.de/DataDictionaryExtended');
docRootNode.setAttribute('Kind','VariableGroup');
docRootNode.setAttribute('Name','CAN Interface (from DBC File)');

msgInfo = messageInfo(candb);
nMessage = length(msgInfo);

for iMessage = 1 : nMessage
  % create doc subnode : message
  msgNode = docNode.createElement('ddObj'); 
%   msgNode = docNode.createElement...
%               (docNode.createElement('ddObj'))
            
  msgNode.setAttribute('Kind','VariableGroup');
  msgNode.setAttribute('Name',msgInfo(iMessage,1).Name); 
  
%   docRootNode.appendChild(msgNode);
%   msgNode.appendChild... 
%         (docNode.createTextNode('1'));
  
  % create message subnode : signal
  
  signals = msgInfo(iMessage,1).Signals;
  nSignals = length(signals);
  for iSignal = 1 : nSignals
    sigInfo = signalInfo(candb, msgInfo(iMessage,1).Name,signals{iSignal,1});
    
    signalNode = msgNode.appendChild...
              (docNode.createElement('ddObj')); 
    signalNode.setAttribute('Kind','Variable');
    signalNode.setAttribute('Name',sigInfo.Name); 
    
%     docRootNode.appendChild(msgNode);
    
    % signal subnode: signal infomation
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty')); 
    signalInfoNode.setAttribute('Name','Description'); 
    signed = 'unsigned';
    if sigInfo.Signed
      signed = 'signed';
    end
    
    signalType = [upper(sigInfo.Class(1)) sigInfo.Class(2:end) ];
    if strfind(sigInfo.Class,'ui')
      signalType = [upper(sigInfo.Class(1:2)) sigInfo.Class(3:end) ];
    end
    
    if sigInfo.SignalSize > 1 
      signalInfoNode.appendChild... 
          (docNode.createTextNode(sprintf('Signal %s. Vector__XXX. CAN format Motorola, CAN start bit: %d, length: %d, %s. World value = %d*%s-%d.', ...
                                  sigInfo.Name,sigInfo.StartBit,sigInfo.SignalSize,signed,sigInfo.Factor,sigInfo.Name,sigInfo.Offset)));
    else
      signalInfoNode.appendChild... 
          (docNode.createTextNode(sprintf('Signal %s. Vector__XXX. CAN format Motorola, CAN start bit: %d, length: %d, %s. World value = %s.', ...
                                  sigInfo.Name,sigInfo.StartBit,sigInfo.SignalSize,signed,sigInfo.Name)));
    end
                                
    
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty'));
    signalInfoNode.setAttribute('Name','Class'); 
    signalInfoNode.appendChild... 
        (docNode.createTextNode('GLOBAL'));
    
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty')); 
    signalInfoNode.setAttribute('Name','Type');
    signalInfoNode.appendChild... 
        (docNode.createTextNode(signalType));
      
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty'));      
    signalInfoNode.setAttribute('Name','Scaling'); 
    signalInfoNode.appendChild... 
        (docNode.createTextNode('./LocalScaling'));
      
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty')); 
    signalInfoNode.setAttribute('Name','Width'); 
    signalInfoNode.appendChild... 
        (docNode.createTextNode(''));
      
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty'));
    signalInfoNode.setAttribute('Name','Value'); 
    signalInfoNode.appendChild... 
        (docNode.createTextNode(''));
      
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty')); 
    signalInfoNode.setAttribute('Name','Min'); 
    signalInfoNode.appendChild... 
        (docNode.createTextNode(sprintf('%d',sigInfo.Minimum)));
      
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty'));
    signalInfoNode.setAttribute('Name','Max'); 
    signalInfoNode.appendChild... 
        (docNode.createTextNode(sprintf('%d',sigInfo.Maximum)));
      
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty')); 
    signalInfoNode.setAttribute('Name','Address'); 
    signalInfoNode.appendChild... 
        (docNode.createTextNode(''));
      
    signalInfoNode = signalNode.appendChild...
              (docNode.createElement('ddProperty'));
    signalInfoNode.setAttribute('Name','NameTemplate'); 
    signalInfoNode.appendChild... 
        (docNode.createTextNode('$D'));
      
    localScaling = signalNode.appendChild...
              (docNode.createElement('ddObj'));
    localScaling.setAttribute('Name','LocalScaling'); 
    localScaling.setAttribute('Kind','ScalingObject');
    
    scalingInfo = localScaling.appendChild...
              (docNode.createElement('ddProperty'));
    scalingInfo.setAttribute('Name','Description'); 
    scalingInfo.appendChild... 
        (docNode.createTextNode('Linear scaling, identical to scaling of source DBC file'));
      
    scalingInfo = localScaling.appendChild...
              (docNode.createElement('ddProperty'));
    scalingInfo.setAttribute('Name','ConversionType'); 
    scalingInfo.appendChild... 
        (docNode.createTextNode('LINEAR'));
      
    scalingInfo = localScaling.appendChild...
              (docNode.createElement('ddProperty'));
    scalingInfo.setAttribute('Name','LSB'); 
    scalingInfo.appendChild... 
        (docNode.createTextNode(sprintf('%d',sigInfo.Factor)));
      
    scalingInfo = localScaling.appendChild...
              (docNode.createElement('ddProperty'));
    scalingInfo.setAttribute('Name','Offset'); 
    scalingInfo.appendChild... 
        (docNode.createTextNode(sprintf('%d',sigInfo.Offset)));
      
    scalingInfo = localScaling.appendChild...
              (docNode.createElement('ddProperty'));
    scalingInfo.setAttribute('Name','Format'); 
    scalingInfo.appendChild... 
        (docNode.createTextNode('%g'));
      
    scalingInfo = localScaling.appendChild...
              (docNode.createElement('ddProperty'));
    scalingInfo.setAttribute('Name','Unit'); 
    scalingInfo.appendChild... 
        (docNode.createTextNode(sigInfo.Units));      
    
  end  
  docRootNode.appendChild(msgNode);
end

xmlwrite('CAN_IO_ddImport.xml',docNode);
% type(xmlFileName);